﻿/*
   Copyright 2013 Dmitry Bratus

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Flower.Services.Data;

namespace Flower.Services
{
    /// <summary>
    /// Queue service interface.
    /// </summary>
    [ServiceContract(Namespace = XmlNamespace.QueueService)]
    public interface IQueueService
    {
        /// <summary>
        /// Puts a message to a queue.
        /// </summary>
        /// <param name="recipient">The recipient of the message.</param>
        /// <param name="message">The message.</param>
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        Guid Enqueue(string recipient, Blob message);

        /// <summary>
        /// Gets a message from a queue.
        /// </summary>
        /// <param name="recipient">The recipient of the message.</param>
        /// <param name="waiterPid">
        /// The id of the process requesting the message. If no message is available, the process
        /// will be switched to the waiting status.
        /// </param>
        /// <returns>The message or null if no message is available.</returns>
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        Blob Dequeue(string recipient, string waiterPid);

        /// <summary>
        /// Gets a list of all known recipients (i.e. having messages or waiters).
        /// 
        /// The recipients are returned in a predefined order, so if there was no
        /// changes in the queue between two calls of this method, the calls will return
        /// the same list. Thus you can read the recipients frame by frame untill you get
        /// an empty list.
        /// </summary>
        /// <param name="start">Zero based index of the first element in the result set to return.</param>
        /// <param name="limit">Zero based index of the element after the last in the result set to return.</param>
        /// <returns>A list of recipient ids. The method returns not more than limit - start elements.</returns>
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        IList<string> GetRecipients(long start, long limit);

        /// <summary>
        /// Gets messages by ids.
        /// </summary>
        /// <param name="ids">Ids of the messages to return.</param>
        /// <returns>
        /// A list of found messages.
        /// 
        /// If the result set doesn't contain messages with some of the 
        /// specified ids, those messages don't exist in the queue.
        /// </returns>
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        IList<QueueServiceMessage> GetMessagesById(IList<Guid> ids);

        /// <summary>
        /// Gets messages by recipient and time frame.
        /// </summary>
        /// <param name="recipients">
        /// Optional. The ids of the recipients whose messages are to be returned. 
        /// If not specified, messages of all recipients are returned.
        /// </param>
        /// <param name="start">Optional. The start of the requested time frame (inclusive).</param>
        /// <param name="end">Optional. The end of the requested time frame (inclusive).</param>
        /// <returns>A list of messages filtered by the recipient and the put time.</returns>
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        IList<QueueServiceMessage> GetMessagesByRecipient(IList<string> recipients, DateTime? start, DateTime? end);

        /// <summary>
        /// Exports recipients' information including messages and waiters.
        /// </summary>
        /// <param name="recipients">The ids of the recipients whose information is be exported.</param>
        /// <returns>The recipient information including messages and waiters.</returns>
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        IList<Recipient> ExportRecipients(IList<string> recipients);

        /// <summary>
        /// Imports recepients' information.
        /// </summary>
        /// <param name="recipients">The recipients' information to be imported.</param>
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        void ImportRecipients(IList<Recipient> recipients);

        /// <summary>
        /// Removes messages by ids.
        /// </summary>
        /// <param name="ids">Ids of the messages to be removed.</param>
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        void RemoveMessages(IList<Guid> ids);
        
        /// <summary>
        /// Removes recipients by ids.
        /// </summary>
        /// <param name="recipients">Ids of the recipients to be removed.</param>
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        void RemoveRecipients(IList<string> recipients);
    }
}
